<template>
    <jb-page class="split-page">
        <div class="flex-col">
            <n-form
                style="margin-top: 24px"
                ref="formRef"
                :model="formData"
                :rules="rules"
                label-placement="left"
                label-width="120"
                require-mark-placement="right-hanging"
            >
                <n-form-item label="文件地址" path="url">
                    <jb-upload
                        v-model="formData.url"
                        :max="1"
                        :multiple="false"
                        accept=".pdf, .doc, .docx, .xls, .xlsx, .txt, .md"
                        save-path="sysnotice/{date(yyMMdd)}/{random(6)}/{ori}"
                    >
                        <div class="flex item-center" style="align-items: center">
                            <n-button type="primary" ghost>
                                <template #icon>
                                    <jb-icon :local="true" icon="material-symbols:upload"></jb-icon>
                                </template>
                                上传文件
                            </n-button>
                        </div>
                    </jb-upload>
                </n-form-item>

                <div class="input-section">
                    <n-form-item label="分块大小" path="chunkSize">
                        <template #label>
                            <div class="flex items-center justify-end">
                                <label>分块大小</label> &nbsp;
                                <n-popover trigger="hover" style="background-color: black;color: white">
                                    <template #trigger>
                                        <n-button text>
                                            <jb-icon :local="true" icon="mingcute:information-line" class="ms-1" width="18" color="#aaaaaa"></jb-icon>
                                        </n-button>
                                    </template>
                                    <span>
                                    文档拆分后，每个片段字数的约值。最大值限制取决于使用的向量化模型token限制。
                                    </span>
                                </n-popover>
                            </div>
                        </template>
                        <n-input-number v-model:value="formData.chunkSize" clearable/>
                    </n-form-item>
                    <n-form-item label="重叠大小" path="chunkOverlap">
                        <template #label>
                            <div class="flex items-center justify-end">
                                <label>重叠大小</label> &nbsp;
                                <n-popover trigger="hover" style="background-color: black;color: white">
                                    <template #trigger>
                                        <n-button text>
                                            <jb-icon :local="true" icon="mingcute:information-line" class="ms-1" width="18" color="#aaaaaa"></jb-icon>
                                        </n-button>
                                    </template>
                                    <span>
                                    每个片段会保留上个片段末尾的部分内容，用于保持前后片段的相关性。<br/>值越大则相关性越高，上下文不容易丢失，但每个片段的重复度也越高。
                                    </span>
                                </n-popover>
                            </div>

                        </template>
                        <n-input-number v-model:value="formData.chunkOverlap" clearable/>
                    </n-form-item>
                </div>
            </n-form>

            <div class="submit-section">
                <n-button type="primary" @click="handleSubmit" :loading="loading">
                    文档分割
                </n-button>
            </div>

            <!-- Results Section -->
            <div class="results-section">
                <n-card title="拆分结果" class="results-card">
                    <template #header-extra>
                        <div style="display: flex; align-items: center; justify-content: end;width: 100%;">
                            共 {{ splitResults.length }} 个片段
                        </div>
                    </template>
                    <div class="results-list">
                        <n-scrollbar>
                            <n-collapse>
                                <n-collapse-item
                                    v-for="(content, index) in splitResults"
                                    :key="index"
                                    :title="'片段 ' + (index + 1)"
                                >
                                    <div class="content-item">
                                        <n-scrollbar style="max-height: 300px">
                                            <p class="content-text">{{ content }}</p>
                                        </n-scrollbar>
                                        <div class="content-footer">
                                            <n-button text type="primary" size="small" @click="copyContent(content)">
                                                <template #icon>
                                                    <jb-icon :local="true" icon="material-symbols:content-copy-outline"/>
                                                </template>
                                                复制内容
                                            </n-button>
                                        </div>
                                    </div>
                                </n-collapse-item>
                            </n-collapse>
                        </n-scrollbar>
                    </div>
                </n-card>
            </div>
        </div>
    </jb-page>
</template>

<script setup>
import {ref} from "vue";
import {JBoltApi} from "@/service/request/index.js";
import {useMessage} from 'naive-ui';

const message = useMessage();
const loading = ref(false);
const splitResults = ref([]);

const formRef = ref(null);

const formData = ref({
    url: '',
    chunkSize: 512,
    chunkOverlap: 100
})

const rules = {
    url: {
        required: true,
        message: '请输入上传文件',
        trigger: 'change'
    },
    chunkSize: [{
        required: true,
        type: 'number',
        message: '请输入分块大小',
        trigger: ['blur', 'change']
    }, {
        type: 'number',
        validator: (rule, value) => {
            if (value === null || value === undefined) return false;
            return value > 0;
        },
        message: '分块大小必须大于0',
        trigger: ['blur', 'change']
    }],
    chunkOverlap: [{
        required: true,
        type: 'number',
        message: '',
        trigger: ['blur', 'change']
    }, {
        type: 'number',
        validator: (rule, value) => {
            if (value === null || value === undefined) return false;
            return value > 0;
        },
        message: '重叠大小必须大于0',
        trigger: ['blur', 'change']
    }, {
        type: 'number',
        validator: (rule, value) => {
            if (value === null || value === undefined) return true;
            const chunkSize = formData.value.chunkSize;
            if (!chunkSize) return true;
            return value <= chunkSize / 2;
        },
        message: '重叠大小不能超过分块大小的一半',
        trigger: ['blur', 'change']
    }]
}

function copyContent(content) {
    if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(content)
            .then(() => {
                $message.success('内容已复制到剪贴板');
            })
            .catch((err) => {
                console.error('复制失败:', err);
            });
    } else {
        console.error('当前浏览器不支持 Clipboard API');
        // 降级方案：使用旧的 execCommand 方法
        fallbackCopyText(content);
    }
}

function fallbackCopyText(text) {
    const textArea = document.createElement('textarea');
    textArea.value = text;
    document.body.appendChild(textArea);
    textArea.select();
    try {
        $message.success('内容已复制到剪贴板');
        document.execCommand('copy');
        // console.log('内容已复制到剪贴板（降级方案）');
    } catch (err) {
        $message.error('复制失败,请手动复制');
        console.error('复制失败（降级方案）:', err);
    }
    document.body.removeChild(textArea);
}

async function handleSubmit() {
    await formRef.value?.validate();
    loading.value = true;
    JBoltApi.tryGet(`/demo/docSplitDemo`, {
        url: formData.value.url,
        chunkSize: formData.value.chunkSize,
        chunkOverlap: formData.value.chunkOverlap
    }).then((result) => {
        splitResults.value = result.data.filter(item => !!item);
    }).catch((error) => {
        console.error(error);
    }).finally(() => {
        loading.value = false;
    });
}
</script>

<style scoped>
.split-page {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.split-page :deep(.n-card) {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.split-page :deep(.n-card-header) {
    flex-shrink: 0;
}

.split-page :deep(.n-card__content) {
    flex: 1;
    overflow: hidden;
    padding: 0 16px 16px;
}

.flex-col {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.input-section {
    display: flex;
    gap: 20px;
    align-items: flex-start;
}

.submit-section {
    flex-shrink: 0;
}

.results-section {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.results-card {
    height: 100%;
}

.results-list {
    height: 100%;
}

.results-list :deep(.n-scrollbar) {
    height: 100%;
}

.results-list :deep(.n-scrollbar-container) {
    height: 100%;
}

.content-item {
    padding: 16px;
    background: #f9f9f9;
    border-radius: 6px;
    margin-bottom: 12px;
}

.content-item:last-child {
    margin-bottom: 0;
}

.content-text {
    margin: 0;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
}

.content-footer {
    display: flex;
    justify-content: flex-end;
    margin-top: 12px;
    padding-top: 8px;
    border-top: 1px solid #eee;
}

:deep(.n-form-item .n-input-number) {
    width: 200px;
}
</style>